"""返回第三方登录网址的视图"""
from rest_framework import status
from rest_framework.response import Response
from rest_framework.views import APIView

from MeiduoMall.utils import tjws
from MeiduoMall.utils.jwt_token import generate
from carts.utils import merge_cart_cookie_to_redis
from oauth import constants
from oauth.models import OAuthQQUser
from oauth.serializers import OAuthQQUserSerializer
from oauth.utiles import OAuthQQ


# url(r'^qq/authorization/$', views.QQAuthURLView.as_view())
class QQAuthURLView(APIView):
    """
    获取QQ登录的url
    """

    def get(self, request):
        """
        提供用于qq登录的url,是点击QQ图标后的跳转去登录qq的地址
        :param request: 可以获取request携带的next参数(type: str)
        :return: qq登录的url
        """
        # 接受成功授权登录后的跳转地址
        next = request.query_params.get('next')
        # 创建QQ辅助工具类对象
        oauth = OAuthQQ(state=next)
        # 获取qq登录的网址
        login_url = oauth.get_qq_login_url()
        return Response({
            "login_url": login_url
        })


# url(r'^qq/user/$', views.QQAuthUserView.as_view())
class QQAuthUserView(APIView):
    """
    QQ登录的用户
    """

    """
    GET /oauth/qq/user/?code=xxx
    用户在QQ都能锅炉成功后,QQ会将用户重定向回我们配置的回调callback网址dev.py中QQ_REDIRECT_URI
    在QQ将用户重定向到此网页时,重定向的网址会携带QQ提供的code参数,用于获取用户信息使用,我们需要将这个code参数发送给后端,在后端中使用code参数向QQ请求用户的身份信息,并查询与该QQ用户绑定的用户
    """
    def get(self, request):
        """获取qq登录的用户数据"""
        # 获取Authorization Code
        code = request.query_params.get("code")
        if not code:
            return Response({
                'message': '缺少code'
            }, status=status.HTTP_400_BAD_REQUEST)

        # 创建QQ辅助工具类对象
        oauth = OAuthQQ()

        # 下面通过code先获取access_token然后获取openid
        try:
            access_token = oauth.get_access_token(code)
            openid = oauth.get_openid(access_token)
        except Exception:
            return Response({
                'message': 'QQ服务异常'
            }, status=status.HTTP_503_SERVICE_UNAVAILABLE)
        # 根据openid判断用户是否存在
        try:
            qq_user = OAuthQQUser.objects.get(openid=openid)
        except OAuthQQUser.DoesNotExist:
            # 用户第一次使用QQ登录
            """
            token = tjws.dumps({
                'openid': openid
            }, constants.SAVE_QQ_USER_TOKEN_EXPIRES)
            此行代码功能与下行代码一样,只是封装的地方不同
            """
            token = oauth.generate_save_user_token(openid)
            return Response({
                'access_token': token
            })
        else:
            # 找到用户生成token,实现状态保持,登录成功
            response = Response({
                'token': generate(qq_user.user),
                'user_id': qq_user.user.id,
                'username': qq_user.user.username
            })

            # 合并cookie/购物车
            response = merge_cart_cookie_to_redis(request, qq_user.user.id, response)

            return response

    """
    项目readme.txt中第三方登录流程4
    如果用户是首次使用QQ登录,则需要绑定用户:
        用户需要填写手机号/密码/图片验证码/短信验证码
        如果用户未在美多商城注册过,则会将手机号作为用户名为用户创建一个美多账户,并绑定用户
        如果用户已在美多商城注册过,则检验密码后直接绑定用户
    POST /oauth/qq/user/
    """
    def post(self, request):
        """
        :param request: mobile/password/sms_code/access_token  均从request.data中获取
        :return: token/id/username
        """
        serializer = OAuthQQUserSerializer(data=request.data)
        # serializer.is_valid(raise_exception=True)
        if not serializer.is_valid():
            return Response({
                'message': serializer.errors
            })
        # 绑定用户,即在OAuthQQUser表中创建一条记录
        user = serializer.save()

        response = Response({
            'token': user.token,
            'user_id': user.id,
            'username': user.username
        })

        # 合并cookie/购物车
        response = merge_cart_cookie_to_redis(request, user.id, response)

        return response
